from fastapi import APIRouter, Query
from fastapi_pagination import Page
from fastapi_pagination.ext.tortoise import paginate

from base.base_schemas import BaseSelectOptionSchema
from utils.auth import public_route
from . import models, schemas
from typing import Optional
from pydantic import UUID4

from .filters import MenuFilter, VisitorFilter

router = APIRouter()


@router.get("/menus", response_model=Page[schemas.MenuOutSchema])
async def get_menus(
    active: Optional[bool] = Query(None),
    title: Optional[str] = Query(None),
    size: Optional[int] = Query(10),
    page: Optional[int] = Query(1),
):
    query = models.Menu.all()
    query = MenuFilter.filter(query, {"active": active, "title": title})
    total = await query.count()
    pages = total // size + 1
    paginated_query = await query.limit(size).offset((page - 1) * size)
    # 获取分页后的菜单 ID 列表
    menu_ids = [menu.id for menu in paginated_query]
    items = await models.Menu.get_tree(id__in=menu_ids)
    return {"total": total, "pages": pages, "size": size, "page": page, "items": items}


@router.get("/menus/list_select_options", response_model=list[BaseSelectOptionSchema])
async def get_menu_list_select_options():
    query = models.Menu.filter()
    data = await query.all()
    return [
        {
            "label": item.title,
            "value": item.id,
            "active": item.active,
        }
        for item in data
    ]


@router.get("/menus/public", response_model=list[schemas.MenuOutSchema])
@public_route()
async def get_public_menus():
    return await models.Menu.get_tree(active=True)


@router.post("/menus", response_model=schemas.MenuOutSchema)
async def create_menu(data: schemas.MenuEditSchema):
    obj = await models.Menu.create(**data.model_dump())
    return await obj.to_dict()


@router.delete("/menus/batch_delete")
async def batch_delete_menus(menu_ids: list[UUID4]):
    await models.Menu.filter(id__in=menu_ids).delete()
    return None


@router.put("/menus/{menu_id}", response_model=schemas.MenuOutSchema)
async def update_menu(menu_id: UUID4, data: schemas.MenuEditSchema):
    obj = await models.Menu.get_or_raise(id=menu_id)
    await obj.update_from_dict(data.model_dump(exclude_unset=True))
    await obj.save()
    return await obj.to_dict()


@router.delete("/menus/{menu_id}")
async def delete_menu(menu_id: UUID4):
    obj = await models.Menu.get_or_raise(id=menu_id)
    await obj.delete()
    return None


@router.get("/global_config", response_model=schemas.GlobalConfigOutSchema)
@public_route()
async def get_global_config():
    config, _ = await models.GlobalConfig.get_or_create(
        defaults={
            "title": "FastAPI Admin",
            "logo_text": "FastAPI Admin",
            "sider_name": "FastAPI Admin",
            "sider_avatar": "https://fastapi-admin.ustclug.org/logo.png",
            "sider_description": "FastAPI Admin",
            "sider_cover": "https://fastapi-admin.ustclug.org/logo.png",
            "index_title": "FastAPI Admin",
            "index_subtitle": "FastAPI Admin",
            "index_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "index_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "category_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "category_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "tag_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "tag_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "archive_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "archive_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "thought_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "thought_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "message_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "message_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
            "thought_cover": "https://h5mkk9qbimbcakvi.public.blob.vercel-storage.com/fastapi_blog/608283811-RynboRRnFx8HGrPizwfzbXjdfnrGIk.png",
            "thought_blurhash": "LdE|P.s+oeW@.AsjWCa#NPacfSWE",
        }
    )
    return await models.GlobalConfig.get_or_raise(id=config.id)


@router.put("/global_config", response_model=schemas.GlobalConfigOutSchema)
async def update_global_config(data: schemas.GlobalConfigEditSchema):
    obj = await models.GlobalConfig.get_or_raise(id=data.id)
    await obj.update_from_dict(data.model_dump(exclude_unset=True))
    await obj.save()
    return obj


@router.get("/visitors", response_model=Page[schemas.VisitorOutSchema])
async def get_visitors(
    ip: Optional[str] = Query(None),
    country: Optional[str] = Query(None),
    region: Optional[str] = Query(None),
    city: Optional[str] = Query(None),
    active: Optional[bool] = Query(None),
):
    query = models.Visitor.all()
    query = VisitorFilter.filter(
        query,
        {
            "ip": ip,
            "country": country,
            "region": region,
            "city": city,
            "active": active,
        },
    )
    return await paginate(query)


@router.get("/visitors/disable/{ip}", response_model=schemas.VisitorOutSchema)
async def disable_visitors(ip: str):
    visitor = await models.Visitor.get_or_raise(ip=ip)
    visitor.active = False
    await visitor.save()
    return visitor


@router.get("/visitors/enable/{ip}", response_model=schemas.VisitorOutSchema)
async def enable_visitors(ip: str):
    visitor = await models.Visitor.get_or_raise(ip=ip)
    visitor.active = True
    await visitor.save()
    return visitor


@router.delete("/visitors/batch_delete")
async def batch_delete_visitors(ids: list[UUID4]):
    await models.Visitor.filter(id__in=ids).delete()
    return None


@router.delete("/visitors/{id}")
async def delete_visitor(id: UUID4):
    visitor = await models.Visitor.get_or_raise(id=id)
    await visitor.delete()
    return None
